package br.com.gsc.vaadin;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;

import br.com.gsc.model.tableMapping.Admin;
import br.com.gsc.model.tableMapping.Company;
import br.com.gsc.model.tableMapping.Operator;
import br.com.gsc.model.tableMapping.Person;
import br.com.gsc.model.tableMapping.Post;
import br.com.gsc.model.tableMapping.Product;
import br.com.gsc.model.tableMapping.Topic;
import br.com.gsc.model.tableMapping.TopicTypes;
import br.com.gsc.model.tableMapping.User;
import br.com.gsc.repository.objRepos.PersonRepository;
import br.com.gsc.repository.objRepos.PostRepository;
import br.com.gsc.repository.objRepos.ProductRepository;
import br.com.gsc.setup.AuthenticationHolder;

import com.github.wolfie.refresher.Refresher;
import com.github.wolfie.refresher.Refresher.RefreshListener;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

@Configurable(preConstruction=true)
@Transactional
public class GenericAnswerWindow extends Window implements ItemClickListener, ClickListener  {

	@AutoGenerated
	private AbsoluteLayout mainLayout;

	@AutoGenerated
	private Panel panel_1;

	@AutoGenerated
	private VerticalLayout verticalLayout_2;

	@AutoGenerated
	private Panel panel_4;

	@AutoGenerated
	private HorizontalLayout horizontalLayout_5;

	@AutoGenerated
	private Button button_1;

	@AutoGenerated
	private Panel panel_2;

	@AutoGenerated
	private VerticalLayout verticalLayout_3;

	private static final long serialVersionUID = 1L;
	
	private List<Product> listOfProducts = new ArrayList<Product>();

	@Autowired
	private ProductRepository proRepo;	
	
	@Autowired
	private PostRepository postRepo;
	
	private TopicTypes windowType;
	@Autowired
	private PersonRepository pRepo;
	@Autowired
	private AuthenticationHolder auth;
	
	private Operator oper;
	private Admin admin;
	private Person person;
	private List<Company> listOfCompanies;
	
	private TextArea tx;
	
	private Topic selectedTopic;
	
	private Timer timer;
	
	private Boolean updated;
	
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public GenericAnswerWindow(TopicTypes type) {
		this.windowType = type;
		this.addComponent(buildMainLayout());
		this.setCaption(type.getName());
//		setupProduct();
//		populatePerguntasPanel();
		timer = new Timer();		
		timer.schedule(new GenericAnswerWindow.Job(auth.getAuthentication().getName()), new Date(),30000);
		final Refresher refresher = new Refresher();
		refresher.setHeight("1px");
		refresher.setWidth("1px");
		refresher.addListener(new JobListener());
		verticalLayout_2.addComponent(refresher);
		this.addListener(new CloseListener() {
			
			@Override
			public void windowClose(CloseEvent e) {
				timer.cancel();				
			}
		});
		// TODO add user code here
	}
	
	public void setupProduct(){
		this.setupProduct("");
	}
	
	@Transactional
	public void setupProduct(String name){
		if(name.isEmpty()){
			person = pRepo.findPersonByID(auth.getAuthentication().getName());
		}else{
			person = pRepo.findPersonByID(name);
		}
		
		listOfProducts = null;
		listOfCompanies = null;
		listOfProducts = new ArrayList<Product>();
		
		if(person instanceof Operator){
			oper = (Operator) person;
			listOfProducts = oper.getListOfProducts();
			listOfCompanies = oper.getListOfCompanies();
			if(listOfProducts.isEmpty() && !listOfCompanies.isEmpty()){
				for(Company comp : listOfCompanies){
					listOfProducts.addAll(comp.getListOfProducts());
				}
			}
		}else if(person instanceof Admin){
			admin = (Admin) person;
			listOfCompanies = admin.getListOfCompanies();
			for(Company comp : listOfCompanies){
				listOfProducts.addAll(comp.getListOfProducts());
			}
		}
		
	}
	
	@Transactional
	public void populatePerguntasPanel(){

		this.panel_2.removeAllComponents();
		for(Product product : listOfProducts){						
			for(Topic top : product.getListOfTopics()){				
				if(top.getTopicType().equals(this.windowType)){
					if(top.getListOfPosts().size() == 0 || top.getListOfPosts().get(top.getListOfPosts().size()-1).getPerson() instanceof User){
					Panel p = new Panel();
					p.setStyleName("teste-panel");
					Tree tree = new Tree();
					tree.addListener(this);
					tree.addItem(top);
					tree.addStyleName("topico");
			    	tree.setChildrenAllowed(top, true);	
					    for(Post post : top.getListOfPosts()){		
					        tree.addItem(post);
					        tree.setParent(post, top);
					    	tree.setChildrenAllowed(post, false);
					    }					   					
					p.addComponent(tree);
					this.panel_2.addComponent(p);
					}
			    }
			}															
		}
	}

	@AutoGenerated
	private AbsoluteLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new AbsoluteLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		if(this.windowType == TopicTypes.QUESTION){
			mainLayout.addStyleName("box-question");
		}else if(this.windowType == TopicTypes.PRAISE){
			mainLayout.addStyleName("box-praise");
		}else if(this.windowType == TopicTypes.PROBLEM){
			mainLayout.addStyleName("box-problem");
		}else{
			mainLayout.addStyleName("box-idea");
		}
		
		// panel_1
		panel_1 = buildPanel_1();
		mainLayout.addComponent(panel_1, "top:0.0px;left:0.0px;");
		
		// top-level component properties
		this.setWidth("545px");
		this.setHeight("360px");
		
		getContent().setSizeFull();
		
		this.setResizable(false);
		
		return mainLayout;
	}

	@AutoGenerated
	private Panel buildPanel_1() {
		// common part: create layout
		panel_1 = new Panel();
		panel_1.setImmediate(false);
		panel_1.setWidth("520px");
		panel_1.setHeight("320px");
		
		// verticalLayout_2
		verticalLayout_2 = buildVerticalLayout_2();
		panel_1.setContent(verticalLayout_2);
		
		return panel_1;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout_2() {
		// common part: create layout
		verticalLayout_2 = new VerticalLayout();
		verticalLayout_2.setImmediate(false);
		verticalLayout_2.setWidth("100.0%");
		verticalLayout_2.setHeight("100.0%");
		verticalLayout_2.setMargin(false);		
		
		// panel_2
		panel_2 = buildPanel_2();
		verticalLayout_2.addComponent(panel_2);
		panel_2.setScrollable(true);
		
		// panel_4
		panel_4 = buildPanel_4();
		verticalLayout_2.addComponent(panel_4);
		
		return verticalLayout_2;
	}

	@AutoGenerated
	private Panel buildPanel_2() {
		// common part: create layout
		panel_2 = new Panel();
		panel_2.setImmediate(false);
		panel_2.setWidth("518px");
		panel_2.setHeight("259px");
		
		// verticalLayout_3
		verticalLayout_3 = new VerticalLayout();
		verticalLayout_3.setImmediate(false);
		verticalLayout_3.setWidth("100.0%");
		verticalLayout_3.setHeight("-1px");
		verticalLayout_3.setMargin(false);
		panel_2.setContent(verticalLayout_3);
		
		return panel_2;
	}

	@AutoGenerated
	private Panel buildPanel_4() {
		// common part: create layout
		panel_4 = new Panel();
		panel_4.setImmediate(false);
		panel_4.setWidth("100.0%");
		panel_4.setHeight("55px");
		
		// verticalLayout_5
		horizontalLayout_5 = buildVerticalLayout_5();
		panel_4.setContent(horizontalLayout_5);
		
		return panel_4;
	}

	@AutoGenerated
	private HorizontalLayout buildVerticalLayout_5() {
		// common part: create layout
		horizontalLayout_5 = new HorizontalLayout();
		horizontalLayout_5.setImmediate(false);
		horizontalLayout_5.setWidth("100.0%");
		horizontalLayout_5.setHeight("100.0%");
		horizontalLayout_5.setMargin(false);
		
		tx = new TextArea();
		tx.setWidth("100%");
		tx.setHeight("40px");
		horizontalLayout_5.addComponent(tx);
		horizontalLayout_5.setComponentAlignment(tx, Alignment.MIDDLE_LEFT);
		horizontalLayout_5.setExpandRatio(tx, 1.0f);
		
		// button_1
		button_1 = new Button();
		button_1.setCaption("Enviar");
		button_1.setImmediate(true);
		button_1.setWidth("120px");
		button_1.setHeight("40px");
		button_1.addListener(this);
		button_1.setStyleName("botao-enviar");
		horizontalLayout_5.addComponent(button_1);
		horizontalLayout_5.setComponentAlignment(button_1, Alignment.MIDDLE_RIGHT);
		
		return horizontalLayout_5;
	}
	
	@Override
	public void itemClick(ItemClickEvent event) {
        if(event.getItemId() instanceof Topic){
        	this.selectedTopic = (Topic) event.getItemId();
        }else{
        	Post post = (Post) event.getItemId();
        	this.selectedTopic = post.getTopic();
        }
        
        if(event.isDoubleClick()){
        	Post post;
        	if(event.getItemId() instanceof Topic){
            	this.selectedTopic = (Topic) event.getItemId();
            	getWindow().showNotification(selectedTopic.getTopicContent());
            }else{
            	post = (Post) event.getItemId();
            	this.selectedTopic = post.getTopic();
            	getWindow().showNotification(post.getContent());
            }
        	
        }
	}

	@Override
	public void buttonClick(ClickEvent event) {
		if(this.selectedTopic != null){
			Post post = new Post();
			Integer max;
			
			if(tx.getValue().toString().length() < 21){
				max = tx.getValue().toString().length();
			}else{
				max = 21;
			}
			this.selectedTopic.setCompanyResponded(true);
			post.setPostTitle(tx.getValue().toString().substring(0, max));
			post.setContent(tx.getValue().toString());
			post.setCreatedIn(new Date());
			post.setPerson(this.person);
			post.setTopic(this.selectedTopic);			
			postRepo.addPost(post);
		    getWindow().showNotification("Sucesso","Mensagem Enviada ao topico :"+this.selectedTopic, Notification.TYPE_TRAY_NOTIFICATION);
		    this.setupProduct();
		    this.populatePerguntasPanel();
		    this.selectedTopic = null;
		}else{
			getWindow().showNotification("Erro","Selecione um topico ou post ", Notification.TYPE_WARNING_MESSAGE);
		}
	}
	
	@Transactional
	class Job extends TimerTask {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		private String name;
		
		public Job(String name){
			this.name = name;
		}
		
		@Override
		public void run() {
			updated = true;
			setupProduct(name);
			populatePerguntasPanel();
		}
		
	}
	
	class JobListener implements RefreshListener{
		@Override
		public void refresh(Refresher source) {
			if(updated){				
				updated = false;
			}
			
		}
	}
	

}
